commonlibsse_ng\skse\interfaces/
load.rs1use crate::rel::version::Version;
11use crate::skse::impls::stab::{
12 PluginHandle, PluginInfo, SKSEInterface, SKSEMessagingInterface, SKSEObjectInterface,
13 SKSEPapyrusInterface, SKSEScaleformInterface, SKSESerializationInterface, SKSETaskInterface,
14 SKSETrampolineInterface,
15};
16use crate::skse::interfaces::query::QueryInterface;
17use core::ffi::{CStr, c_void};
18
19#[derive(Debug)]
25#[repr(transparent)]
26pub struct LoadInterface(SKSEInterface);
27
28pub unsafe trait QueryTarget: private::Sealed {
35 #[inline]
40 fn cast(ptr: *mut c_void) -> &'static Self
41 where
42 Self: Sized,
43 {
44 debug_assert!(!ptr.is_null(), "SKSE interface query returned null");
45 unsafe { &*(ptr as *const Self) }
46 }
47
48 const ID: u32;
50}
51
52macro_rules! impl_query_target {
53 ($($t:ty => $id:expr),*) => {
54 $(
55 unsafe impl QueryTarget for $t {
56 const ID: u32 = $id;
57 }
58 )*
59 };
60}
61
62mod private {
64 use super::*;
65
66 pub trait Sealed {}
67 impl Sealed for SKSEScaleformInterface {}
68 impl Sealed for SKSEPapyrusInterface {}
69 impl Sealed for SKSESerializationInterface {}
70 impl Sealed for SKSETaskInterface {}
71 impl Sealed for SKSEMessagingInterface {}
72 impl Sealed for SKSEObjectInterface {}
73 impl Sealed for SKSETrampolineInterface {}
74}
75
76impl_query_target!(
77 SKSEScaleformInterface => 1,
78 SKSEPapyrusInterface => 2,
79 SKSESerializationInterface => 3,
80 SKSETaskInterface => 4,
81 SKSEMessagingInterface => 5,
82 SKSEObjectInterface => 6,
83 SKSETrampolineInterface => 7
84);
85
86impl LoadInterface {
87 #[inline]
89 pub fn get_plugin_handle(&self) -> PluginHandle {
90 unsafe { (self.0.GetPluginHandle)() }
91 }
92
93 #[inline]
97 pub fn get_plugin_info(&self, name: &CStr) -> *const PluginInfo {
98 unsafe { (self.0.GetPluginInfo)(name.as_ptr()) }
99 }
100
101 #[inline]
103 pub fn get_release_index(&self) -> u32 {
104 unsafe { (self.0.GetReleaseIndex)() }
105 }
106
107 #[inline]
109 pub fn query_interface<T: QueryTarget>(&self) -> &'static T {
110 let fn_table = unsafe { (self.0.QueryInterface)(T::ID) };
111 T::cast(fn_table)
112 }
113}
114
115impl QueryInterface for LoadInterface {
116 #[inline]
117 fn editor_version(&self) -> u32 {
118 self.0.editorVersion
119 }
120
121 #[inline]
122 fn is_editor(&self) -> bool {
123 self.0.isEditor != 0
124 }
125
126 #[inline]
127 fn runtime_version(&self) -> Version {
128 let packed = self.0.runtimeVersion;
129 let major = ((packed & 0xFF000000) >> 24) as u16;
130 let minor = ((packed & 0x00FF0000) >> 16) as u16;
131 let revision = ((packed & 0x0000FFF0) >> 4) as u16;
132 let build = (packed & 0x0000000F) as u16;
133 Version::new(major, minor, revision, build)
134 }
135
136 #[inline]
137 fn skse_version(&self) -> u32 {
138 self.0.skseVersion
139 }
140}